<template>
  <div class="panel-tab__content">
    <div v-if="!type">&nbsp;</div>
    <el-form
      key="flowOtherProperty"
      ref="flowOtherPropertyForm"
      v-else-if="type === 'Process'"
      label-width="100px"
      :model="formData"
      @submit.native.prevent
      :rules="rules">
      <!-- 撤回类型 -->
      <el-form-item prop="cancelType">
        <template slot="label">
          <el-tooltip key="withdrawType" placement="top-start" @click.stop.prevent>
            <div slot="content" class="flowDesignPropertyInputTipBox">
              <p>{{ $t('withdrawTypeTip') }}</p>
            </div>
            <i class="el-icon-question"></i>
          </el-tooltip>
          <span style="margin-left:2px">{{ $t('withdrawType') }}</span>
        </template>
        <el-select v-model="formData.cancelType">
          <el-option :value="10" :key="10" :label="$t('force')"></el-option>
          <el-option :value="20" :key="20" :label="$t('nonforce')"></el-option>
        </el-select>
      </el-form-item>
      <!-- 文件个数 -->
      <el-form-item prop="fileCount">
        <template slot="label">
          <el-tooltip key="withdrawType" placement="top-start" @click.stop.prevent>
            <div slot="content" class="flowDesignPropertyInputTipBox">
              <p>{{ $t('fileCountTip') }}</p>
            </div>
            <i class="el-icon-question"></i>
          </el-tooltip>
          <span style="margin-left:2px">{{ $t('fileCount') }}</span>
        </template>
        <el-input v-model="formData.fileCount" :min="1" :max="100"></el-input>
      </el-form-item>
      <!-- 文件大小 -->
      <el-form-item prop="fileSize">
        <template slot="label">
          <el-tooltip key="withdrawType" placement="top-start" @click.stop.prevent>
            <div slot="content" class="flowDesignPropertyInputTipBox">
              <p>{{ $t('fileSizeTip') }}</p>
            </div>
            <i class="el-icon-question"></i>
          </el-tooltip>
          <span style="margin-left:2px">{{ $t('fileSize') }}</span>
        </template>
        <el-input placeholder="" v-model="formData.fileSize">
          <template slot="append">M</template>
        </el-input>
      </el-form-item>
      <!-- 触达提醒 -->
      <el-form-item required>
        <template slot="label">
          <el-tooltip key="withdrawType" placement="top-start" @click.stop.prevent>
            <div slot="content" class="flowDesignPropertyInputTipBox">
              <p>{{ $t('touchReminderTip') }}</p>
            </div>
            <i class="el-icon-question"></i>
          </el-tooltip>
          <span style="margin-left:2px">{{ $t('touchReminder') }}</span>
        </template>
        <el-switch
          v-model="formData.canTouchNotice"
          :inactive-value="0"
          :active-value="1"
          active-color="#4388a6"
          inactive-color="#bfbfbf">
        </el-switch>
      </el-form-item>
      <!-- 流程备注 -->
      <el-form-item :label="$t('flowRemark')">
        <el-input
          class="flowRemarkInput"
          type="textarea"
          v-model="formData.remark"
          :autosize="{ minRows: 10 }"
          maxlength="200"
          show-word-limit
          placeholder="" />
      </el-form-item>
    </el-form>
    <!-- 节点的其它属性 -->
    <el-form
      :key="'nodeOtherProperty'+id"
      ref="nodeOtherPropertyForm"
      v-else
      label-width="100px"
      :model="formData"
      @submit.native.prevent>
      <el-row :gutter="16">
        <el-col :xl="12" :lg="24">
          <!-- 结果通知 -->
          <el-form-item>
            <template slot="label">
              <el-tooltip key="resultNoticeTip" placement="top-start" @click.stop.prevent>
                <div slot="content" class="flowDesignPropertyInputTipBox">
                  <p>{{ $t('resultNoticeTip') }}</p>
                </div>
                <i class="el-icon-question"></i>
              </el-tooltip>
              <span style="margin-left:2px">{{ $t('resultNotice') }}</span>
            </template>
            <el-switch
              v-model="nodeOtherConfig.canResultNotice"
              :inactive-value="0"
              :active-value="1"
              active-color="#4388a6"
              inactive-color="#bfbfbf"
              @change="updateNodeOtherConfig('canResultNotice')">
            </el-switch>
          </el-form-item>
        </el-col>
        <el-col :xl="12" :lg="24">
          <!-- 撤回通知 -->
          <el-form-item>
            <template slot="label">
              <el-tooltip key="cancelNoticeTip" placement="top-start" @click.stop.prevent>
                <div slot="content" class="flowDesignPropertyInputTipBox">
                  <p>{{ $t('cancelNoticeTip') }}</p>
                </div>
                <i class="el-icon-question"></i>
              </el-tooltip>
              <span style="margin-left:2px">{{ $t('cancelNotice') }}</span>
            </template>
            <el-switch
              v-model="nodeOtherConfig.canInstanceCancelNotice"
              :inactive-value="0"
              :active-value="1"
              active-color="#4388a6"
              inactive-color="#bfbfbf"
              @change="updateNodeOtherConfig('canInstanceCancelNotice')">
            </el-switch>
          </el-form-item>
        </el-col>
      </el-row>
      <!-- 节点备注 -->
      <el-form-item :label="$t('nodeRemark')">
        <el-input
          class="flowRemarkInput"
          type="textarea"
          v-model="documentation"
          :autosize="{ minRows: 8 }"
          maxlength="200"
          show-word-limit
          placeholder=""
          @change="updateDocumentation" />
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
const initNodeOtherConfig = {
  // 结果通知
  canResultNotice: 0,
  // 撤回通知
  canInstanceCancelNotice: 0
}
export default {
  name: 'ElementOtherConfig',
  inject: {
    prefix: 'prefix'
  },
  props: {
    id: {
      type: String,
      default: ''
    },
    type: {
      type: String,
      default: ''
    }
  },
  data () {
    const validateFileCount = (rule, value, callback) => {
      if (!value) {
        callback()
        return
      }
      // eslint-disable-next-line no-param-reassign
      value += ''
      // eslint-disable-next-line no-param-reassign
      value = value.replace(/^\s+|\s+$/g, '')
      if (value.length === 0) {
        callback()
        return
      }
      if (!/^[1-9]\d*$/.test(value)) {
        // eslint-disable-next-line callback-return
        callback(new Error(this.$t('inputPositiveIntegerTip')))
      }
      if (value > 2147483647) {
        // eslint-disable-next-line callback-return
        callback(new Error(this.$t('maxInputNumber').replace('__NUM__', 2147483647)))
      }
      callback()
    }
    const validateFileSize = (rule, value, callback) => {
      if (/\D/.test(value) || value < 1 || value > 10) {
        const msg = this.$t('rangeIntegerErrorTip').replace('X~Y', '1~10')
        // eslint-disable-next-line callback-return
        callback(new Error(msg))
      }
      callback()
    }
    return {
      documentation: '',
      rules: {
        cancelType: [
          { required: true, message: this.$t('pleaseInput'), trigger: 'change' }
        ],
        fileCount: [
          { validator: validateFileCount, trigger: 'change' }
        ],
        fileSize: [
          { required: true, message: this.$t('pleaseInput'), trigger: 'change' },
          { validator: validateFileSize, trigger: 'change' }
        ]
      },
      // 节点其它配置
      nodeOtherConfig: {
        ...initNodeOtherConfig
      },
      bpmnElement: null,
      bpmnElementPropertyList: [],
      otherExtensionList: []
    }
  },
  computed: {
    formData () {
      return this.$store.state.flowDesign.formData
    }
  },
  watch: {
    id: {
      immediate: true,
      handler (type) {
        if (type === 'Process') {
          return
        }
        if (this.id && this.id.length) {
          this.$nextTick(() => {
            this.resetDocumentation()
            this.resetNodeOtherConfig()
          })
        }
      }
    }
  },
  methods: {
    // 初始化节点备注信息
    resetDocumentation () {
      this.documentation = ''
      if (window.bpmnInstances.bpmnElement.businessObject) {
        const documentations = window.bpmnInstances.bpmnElement.businessObject.documentation
        this.documentation = documentations && documentations.length ? documentations[0].text : ''
      }
    },
    // 初始化结果通知和撤回通知自定义属性
    resetNodeOtherConfig () {
      this.nodeOtherConfig = {
        ...initNodeOtherConfig
      }
      this.bpmnElement = window.bpmnInstances.bpmnElement
      this.otherExtensionList = [] // 其他扩展配置
      // 是否需要添加flow:type属性值为mail的服务(为了解决保存时后端可以正常保存)
      const needFieldElTask = ['ServiceTask', 'SendTask'].includes(this.type)
      let bpmnElementProperties = []
      if (this.bpmnElement.businessObject && this.bpmnElement.businessObject.extensionElements) {
        if (this.bpmnElement.businessObject.extensionElements.values) {
          bpmnElementProperties = this.bpmnElement.businessObject.extensionElements.values.filter(ex => {
            if (ex.$type !== `${this.prefix}:Properties`) {
              this.otherExtensionList.push(ex)
            }
            return ex.$type === `${this.prefix}:Properties`
          })
        }
        // 处理服务任务和发送任务标签上的flow:type属性
        if (needFieldElTask && this.bpmnElement.businessObject.type !== 'mail') {
          window.bpmnInstances.modeling.updateProperties(this.bpmnElement, { type: 'mail' })
        }
      }
      // 保存所有的 扩展属性字段
      this.bpmnElementPropertyList = bpmnElementProperties.reduce((pre, current) => pre.concat(current.values), [])
      // 在自定义属性中如果没有包含结果通知与撤回通知则追加，有则取最新值start
      const newPropertyObjects = []
      // 是否需要添加flowable:Field自定义标签
      const customFieldFlag = needFieldElTask &&
      !this.otherExtensionList.some(item => item.$type === `${this.prefix}:Field`)
      // eslint-disable-next-line no-restricted-syntax
      for (const key in this.nodeOtherConfig) {
        const obj = this.bpmnElementPropertyList.find(item => item.name === key)
        if (obj) {
          this.nodeOtherConfig[key] = obj.value * 1
        } else {
          const newPropertyObject = window.bpmnInstances.moddle.create(`${this.prefix}:Property`,
            { name: key, value: this.nodeOtherConfig[key] })
          newPropertyObjects.push(newPropertyObject)
        }
      }
      // 当未添加Property标签时或者需要添加flowable:Field自定义标签时需要更新扩展标签
      if (newPropertyObjects.length || customFieldFlag) {
        const values = this.bpmnElementPropertyList.concat(newPropertyObjects)
        const propertiesObject = window.bpmnInstances.moddle.create(`${this.prefix}:Properties`, {
          values
        })
        const tags = [propertiesObject].concat(customFieldFlag ? this.addCustomFieldElement() : [])
        this.updateElementExtensions(tags)
        this.bpmnElementPropertyList = values
      }
      // 在自定义属性中如果没有包含结果通知与撤回通知则追加，有则取最新值end
    },
    // 修改结果通知和撤回通知自定义属性
    updateNodeOtherConfig (key) {
      const editingPropertyIndex = this.bpmnElementPropertyList.findIndex(item => item.name === key)
      window.bpmnInstances.modeling.updateModdleProperties(this.bpmnElement,
        this.bpmnElementPropertyList[editingPropertyIndex],
        {
          name: key,
          value: this.nodeOtherConfig[key]
        })
    },
    updateElementExtensions (properties) {
      const extensions = window.bpmnInstances.moddle.create('bpmn:ExtensionElements', {
        values: this.otherExtensionList.concat(properties)
      })
      window.bpmnInstances.modeling.updateProperties(this.bpmnElement, {
        extensionElements: extensions
      })
    },
    updateDocumentation () {
      (this.bpmnElement && this.bpmnElement.id === this.id) ||
      (this.bpmnElement = window.bpmnInstances.elementRegistry.get(this.id))
      const documentation = window.bpmnInstances.bpmnFactory.create('bpmn:Documentation', { text: this.documentation })
      window.bpmnInstances.modeling.updateProperties(this.bpmnElement, {
        documentation: [documentation]
      })
    },
    validateData () {
      return new Promise((resolve) => {
        if (this.$refs.flowOtherPropertyForm) {
          this.$refs.flowOtherPropertyForm.validate((valid) => {
            if (valid) {
              resolve(true)
            } else {
              resolve('other')
            }
          })
        }
        resolve(true)
      })
    },
    addCustomFieldElement () {
      const elConfig = [ {
        type: 'Field',
        attrs: [{
          name: 'name',
          value: 'text'
        }],
        children: [{
          type: 'String',
          body: 'Hello world'
        }]
      }, {
        type: 'Field',
        attrs: [{
          name: 'name',
          value: 'to'
        }],
        children: [{
          type: 'String',
          body: 'aa@bb.org'
        }]
      }]
      const filedEls = []
      elConfig.forEach(item => {
        const attrs = {}
        item.attrs.forEach(attr => {
          attrs[attr.name] = attr.value
        })
        const values = []
        item.children.forEach(child => {
          const stringEl = window.bpmnInstances.moddle.create(this.prefix + ':' + child.type, {
            body: child.body
          })
          values.push(stringEl)
        })
        const filedEl = window.bpmnInstances.moddle.create(this.prefix + ':' + item.type, { ...attrs, values })
        filedEls.push(filedEl)
      })
      return filedEls
    }
  },
  beforeDestroy () {
    this.bpmnElement = null
  }
}
</script>
<style lang="less">
.flowRemarkInput {
  &.el-textarea {
    .el-input__count {
      bottom: -30px;
      background-color: transparent;
    }
  }
}
</style>
